package com.kcht.np.common.jwt;

import com.kcht.np.common.entrypoint.JwtAuthenticationEntryPoint;
import com.kcht.np.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;


@Slf4j
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenConverter jwtTokenConverter;
    @Autowired
    private JwtAuthenticationEntryPoint authenticationEntryPoint;
    @Autowired
    private SysUserService sysUserService;
    /**
     * 获取当前登录用户的信息
     * */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        // 获取 Request 中的请求头为 “ Authorization ” 的 token 值
        String completeToken = request.getHeader(this.jwtTokenConverter.getTokenHeader());
        // 验证 值是否以"Bearer "开头
        if (completeToken != null && completeToken.startsWith(this.jwtTokenConverter.getTokenHead())) {
            // 截取token中"Bearer "后面的值，
            final String tokenValue = jwtTokenConverter.interceptCompleteToken(completeToken);
            // 根据 token值，获取 用户的 username
            String username = jwtTokenConverter.getUsernameFromToken(tokenValue);
            // 验证用户账号是否合法
            if (username != null) {
                // 根据 username 去 redis 中查询 user 数据，足够信任token的情况下，可以省略这一步
                JwtUser userDetails;
                try {
                    userDetails = sysUserService.getJwtUser(username);
                    log.debug("当前在线的用户是 : {} ", username);
                } catch (AuthenticationException ex) {
                    log.debug(ex.getMessage());
                    SecurityContextHolder.clearContext();
                    this.authenticationEntryPoint.commence(request, response, ex);
                    return;
                }
                List<SimpleGrantedAuthority> authorities =
                        userDetails.getAuthoritiesCol().stream()
                                .map(SimpleGrantedAuthority::new)
                                .collect(Collectors.toList());
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                        userDetails, null,authorities );
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
        chain.doFilter(request, response);
    }
}
